package controllers

import (
	"database/sql"
	"encoding/csv"
	"errors"
	"fmt"
	"io"
	"os"
	"strings"
	"time"

	"github.com/astaxie/beego/orm"

	"fanhantech.com/tagdata/models"
	"github.com/astaxie/beego"
)

type DataController struct {
	beego.Controller
}

// Get /data [get]
func (c *DataController) Get() {
	c.TplName = "data.html"
}

type ProjectData struct {
	Tasks []models.DataCountProject `json:"tasks"`
}

func (c *DataController) GetProjectData() {
	data := new(models.DataCountProject)
	results := new(ProjectData)
	results.Tasks = data.GetAll()

	c.Data["json"] = results
	c.ServeJSON()
}

func (c *DataController) GetCommitData() {
	date, _ := c.GetInt64("date")
	t := time.Unix(date, 0)

	data := new(models.DataCountProjectDate)
	results := data.GetByDate(t)

	c.Data["json"] = results
	c.ServeJSON()
}

func (c *DataController) GetReviewData() {
	date, _ := c.GetInt64("date")
	t := time.Unix(date, 0)

	data := new(models.DataCountReviewDate)
	results := data.GetByDate(t)

	c.Data["json"] = results
	c.ServeJSON()
}

func (c *DataController) DownloadProjectData() {
	// project := c.GetString("project")
	var logPrefix = "[DownloadProjectData]"
	var err error
	// 从数据库查询
	var lists []orm.ParamsList
	o := orm.NewOrm()
	num, err := o.QueryTable("fh_task").Filter("project_id", 1).Filter("status", 30).Limit(-1).ValuesList(&lists, "id", "question", "answer")
	if err != nil {
		beego.Error(logPrefix, "query database error:", err.Error())
		c.Abort("401")
		return
	}
	beego.Info(logPrefix, "query rows:", num)
	// 根据时间创建文件
	filename := "ertongju-" + time.Now().Format(time.RFC3339) + ".csv"
	f, err := os.Create(filename)
	if err != nil {
		beego.Error(err)
		c.Abort("401")
		return
	}
	// 写入csv文件
	csv := csv.NewWriter(f)
	for _, row := range lists {
		var record []string
		for _, item := range row {
			record = append(record, fmt.Sprintf("%v", item))
		}
		err = csv.Write(record)
		if err != nil {
			beego.Error(err)
		}
	}
	// flush
	csv.Flush()
	f.Close()

	c.Ctx.Output.Download(filename)
}

func (c *DataController) UploadProjectData() {
	// project := c.GetString("project")
	var err error
	var res sql.Result
	var logPrefix = "[UploadProjectData]"
	f, _, err := c.GetFile("file")
	if err != nil {
		beego.Error(logPrefix, "get file error:", err.Error())
		c.CustomAbort(400, "获取文件失败"+err.Error())
		return
	}
	defer f.Close()

	o := orm.NewOrm()
	o.Raw("DROP TABLE IF EXISTS temp_task;").Exec()
	sqlstr := "CREATE TEMPORARY TABLE temp_task (id bigint(20) not null,review tinyint(8) unsigned NOT NULL);"
	_, err = o.Raw(sqlstr).Exec()
	if err != nil {
		beego.Error(logPrefix, "create temp_task table error:", err.Error())
		c.CustomAbort(400, "创建临时表失败"+err.Error())
		return
	}

	csvReader := csv.NewReader(f)
	for {
		var record []string
		record, err = csvReader.Read()
		if err == io.EOF {
			err = nil
			break
		}
		if err != nil {
			beego.Error(logPrefix, "csv read record error:", err.Error())
			break
		}
		if len(record) != 4 {
			err = errors.New(strings.Join(record, " "))
			beego.Error(logPrefix, "record length not 4 error:", err.Error())
			break
		}

		res, err = o.Raw("insert into temp_task value (?, ?)", record[0], record[3]).Exec()
		if err != nil {
			beego.Error(logPrefix, "insert into temp_task error:", err.Error())
			break
		}
	}

	if err != nil {
		beego.Error(logPrefix, err)
		c.CustomAbort(400, "记录处理失败"+err.Error())
		return
	}

	res, err = o.Raw("update fh_task, temp_task set fh_task.status=99 where fh_task.id=temp_task.id and temp_task.review=1;").Exec()
	if err != nil {
		beego.Error(logPrefix, "update status=99 error:", err.Error())
		c.CustomAbort(400, "更新数据失败"+err.Error())
		return
	}
	okNums, _ := res.RowsAffected()
	beego.Info()

	res, err = o.Raw("update fh_task, temp_task set fh_task.status=40 where fh_task.id=temp_task.id and temp_task.review=2;").Exec()
	if err != nil {
		beego.Error(logPrefix, "update status=40 error:", err.Error())
		c.CustomAbort(400, "更新数据失败"+err.Error())
		return
	}
	nokNums, _ := res.RowsAffected()

	sqlstr = `REPLACE INTO data_count_project (project,status,count,updated)SELECT b.name AS 'project', '待审核', count(*) as 'count', now()
	FROM
		fh_task a
			INNER JOIN
		fh_project b ON a.project_id = b.id
		WHERE
			a.status in (22,30,102)
		GROUP BY b.name;`
	o.Raw(sqlstr).Exec()

	c.Ctx.WriteString(fmt.Sprintf("更新数据成功, 合格%v条, 不合格%v条", okNums, nokNums))
}
